#include "MainWindow.h"

#include "Creature.h"
#include "HumanCreature.h"
#include "HalfHumanCreature.h"
#include "BasicCreature.h"
#include "QuadrupedCreature.h"
#include "Constraint.h"

#include <QtGui/QClipboard>

namespace jcrada {

    void MainWindow::setCreatureBodyCount( int count ) {
        if (getCreature().getNumberOfBodyParts() == count) {
            return;
        }
        //        getCreature().setBodyCount(count);
        //        getCreature().setConstraintCount(count - 1);
    }

    void MainWindow::setCreatureConstraintCount( int count ) {
        if (getCreature().getNumberOfConstraints() == count) {
            return;
        }
        //        getCreature().setConstraintCount(count);
        //        getCreature().setBodyCount(count + 1);
    }

    //Creature

    void MainWindow::setCreature( Creature& creature ) {
        if (this->_creature) {
            if (this->_creature == getSimulationThread().getSimulator().currentCreature()) {
                getSimulationThread().getSimulator().removeCreature(this->_creature);
            }
            //            this->_creature->destroy();
            delete this->_creature;
        }
        this->_creature = &creature;
    }

    void MainWindow::changedCreature( int index ) {
        switch (index) {
                ////            case 0: setCreature(*new Creature());
                ////                break;
                ////            case 1: setCreature(*new BasicCreature());
                ////                break;
                ////            case 2: setCreature(*new QuadrupedCreature());
                ////                break;
                ////            case 3: setCreature(*new HumanCreature());
                ////                break;
                ////            case 4: setCreature(*new HalfHumanCreature());
                ////                break;
                //            default:
                //                DEBUG(TO_STRING(index));
                //                assert(0);
        }

        getUiInspector().sbx_bodies->setEnabled(index == 0);
        getUiInspector().sbx_constraints->setEnabled(index == 0);
        getUiInspector().btn_creature_add->setEnabled(index > 0);
        getUiInspector().btn_create_creature->setEnabled(index > 0);

        getUiInspector().sbx_bodies->setValue(getCreature().getNumberOfBodyParts());
        getUiInspector().sbx_constraints->setValue(getCreature().getNumberOfConstraints());
        //        getUiInspector().sbx_hidden_layers->setValue(getCreature().getHiddenLayers());
        //        getUiInspector().sbx_neurons_per_layer->setValue(getCreature().getNeuronsPerLayer());
    }

    void MainWindow::createCreature( ) {
        Creature* prv_creature = getSimulationThread().getSimulator().currentCreature();
        if (prv_creature) {
            getSimulationThread().getSimulator().removeCreature(prv_creature);
            DEBUGM;
            if (&getCreature() != prv_creature) {
                DEBUGM;
                delete prv_creature;
            }
        }

        //        getCreature().setHiddenLayers(getUiInspector().sbx_hidden_layers->value());
        //        getCreature().setNeuronsPerLayer(getUiInspector().sbx_neurons_per_layer->value());

        DEBUGM;
    }

    void MainWindow::addCreatureToWorld( ) {
        Creature* prv_creature = getSimulationThread().getSimulator().currentCreature();
        if (prv_creature) {
            getSimulationThread().getSimulator().removeCreature(prv_creature);
            if (&getCreature() != prv_creature) {
                delete prv_creature;
            }
        }
        getSimulationThread().getSimulator().reset();
        getSimulationThread().getSimulator().addCreature(&getCreature());
    }

    void MainWindow::onCreatureRemoved( ) {
        //        getRendererThread().getRenderer().getSelectedBodies().clear();
    }

    void MainWindow::onCreatureAdded( ) {
        getUiInspector().lst_bodies->clear();
        getUiInspector().lst_constraints->clear();
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {
            for (int i = 0; i < creature->getNumberOfBodyParts(); ++i) {
                getUiInspector().lst_bodies->addItem(QString(creature->getBodyPart(i).getName().c_str()));
            }
            for (int i = 0; i < creature->getNumberOfConstraints(); ++i) {
                getUiInspector().lst_constraints->addItem(QString(creature->getConstraint(i).getName().c_str()));
            }
        }
        getSimulationThread().getSimulator().getLock().unlock();
    }

    //    void MainWindow::onChangedBodySelection( ) {
    //        getSimulatorThread().getSimulator().getLock().lockForRead();
    //        Creature* creature = getSimulatorThread().getSimulator().currentCreature();
    //        if (creature) {
    //            getUiInspector().lst_bodies->clear();
    //            getUiInspector().lst_body_details->clear();
    //            const std::vector<btRigidBody*>& bodies = getRendererThread().getRenderer().getSelectedBodies();
    //            DEBUGM;
    //            for (std::vector<btRigidBody*>::const_iterator it = bodies.begin();
    //                    it != bodies.end(); ++it) {
    //                for (int i = 0; i < creature->getBodyCount(); ++i) {
    //                    if (creature->getBody(i)->getRigidBody() == *it) {
    //                        getUiInspector().lst_bodies->item(i)->setSelected(true);
    //                        getUiInspector().lst_bodies->scrollToItem(getUiInspector().lst_bodies->item(i));
    //                    }
    //                }
    //            }
    //            DEBUGM;
    //        }
    //        getSimulatorThread().getSimulator().getLock().unlock();
    //    }

    void MainWindow::onBodyItemSelectionChanged( ) {
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature && creature->getNumberOfBodyParts() == getUiInspector().lst_bodies->count()) {
            double mass = 0.0;
            double size_x = 0.0, size_y = 0.0, size_z = 0.0;
            getUiInspector().lst_body_details->clear();
            for (int i = 0; i < getUiInspector().lst_bodies->count(); ++i) {
                if (getUiInspector().lst_bodies->item(i)->isSelected()) {
                    getRendererThread().getRenderer().selectBody(
                            true, creature->getBodyPart(i).getRigidBody());
//                    creature->setSelected(i);
                    {
                        showBodyDetails(*creature, creature->getBodyPart(i));
                        mass += creature->getBodyPart(i).getMass();
                        size_x += creature->getBodyPart(i).getSizeX();
                        size_y += creature->getBodyPart(i).getSizeY();
                        size_z += creature->getBodyPart(i).getSizeZ();
                    }
                } else {
                    getRendererThread().getRenderer().deselectBody(
                            creature->getBodyPart(i).getRigidBody());
                }
            }
            getUiInspector().led_mass->setText(QString(TO_STRING(mass).c_str()));
            getUiInspector().led_size->setText(
                    QString(("[" + TO_STRING(size_x) + " ; " +
                    TO_STRING(size_y) + " ; " + TO_STRING(size_z) + "]").c_str()));
        }
        getSimulationThread().getSimulator().getLock().unlock();
    }

    void MainWindow::showBodyDetails( const Creature& creature, const BodyPart& body ) {
        getUiInspector().lst_body_details->addItem(QString(
                body.getName().c_str()));
        getUiInspector().lst_body_details->addItem(QString(
                ("  Mass: " + TO_STRING(body.getMass())).c_str()));
        getUiInspector().lst_body_details->addItem(QString(
                ("  Torque: " + TO_STRING(body.getMaxTorque())).c_str()));
        getUiInspector().lst_body_details->addItem(QString(
                std::string("  Size").c_str()));
        getUiInspector().lst_body_details->addItem(QString(
                ("  [x]: " + TO_STRING(body.getSizeX())).c_str()));
        getUiInspector().lst_body_details->addItem(QString(
                ("  [y]: " + TO_STRING(body.getSizeY())).c_str()));
        getUiInspector().lst_body_details->addItem(QString(
                ("  [z]: " + TO_STRING(body.getSizeZ())).c_str()));
        //Angles

        BodyPart* parent = body.getParentId() == Creature::B_NONE
                ? NULL : &creature.getBodyPart(body.getParentId());
        if (parent) {
            getUiInspector().lst_body_details->addItem(QString(
                    ("  Parent: " + parent->getName()).c_str()));
            //            getUiInspector().lst_body_details->addItem(QString(std::string("  Angles:").c_str()));
            //            getUiInspector().lst_body_details->addItem(QString(
            //                    ("   XY:" + TO_STRING(
            //                    MathUtil::getAngle(MathUtil::XY,
            //                    parent->getRigidBody()->getCenterOfMassPosition(),
            //                    body.getRigidBody()->getCenterOfMassPosition()))).c_str()));
            //            getUiInspector().lst_body_details->addItem(QString(
            //                    ("   YZ:" + TO_STRING(
            //                    MathUtil::getAngle(MathUtil::YZ,
            //                    parent->getRigidBody()->getCenterOfMassPosition(),
            //                    body.getRigidBody()->getCenterOfMassPosition()))).c_str()));
            //            getUiInspector().lst_body_details->addItem(QString(
            //                    ("   ZX:" + TO_STRING(
            //                    MathUtil::getAngle(MathUtil::ZX,
            //                    parent->getRigidBody()->getCenterOfMassPosition(),
            //                    body.getRigidBody()->getCenterOfMassPosition()))).c_str()));
        }
    }

    //Forces...

    void MainWindow::setCreatureImpulse( double value ) {
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {
            BDEBUG("setting impulse: " + TO_STRING(value));
        }
    }

    void MainWindow::duplicateForces( ) {
        getUiInspector().sbx_force_x->setValue(getUiInspector().sbx_force_x->value() * 2.0);
        getUiInspector().sbx_force_y->setValue(getUiInspector().sbx_force_y->value() * 2.0);
        getUiInspector().sbx_force_z->setValue(getUiInspector().sbx_force_z->value() * 2.0);
    }

    void MainWindow::forceChanged( double value ) {
        if (getUiInspector().cbx_force_each_step->isChecked()) {
            applyForce(FT_EACH_STEP);
        }
    }

    void MainWindow::applyForce( eForceType type ) {
        bool play = getSimulationThread().getSimulator().isPlaying();
        if (play) {
            pause();
        }
        getSimulationThread().wait();
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {

            if (type == FT_NONE) {
                for (int i = 0; i < creature->getNumberOfBodyParts(); ++i) {
                    creature->getBodyPart(i).getRigidBody()->clearForces();
                }
                getUiInspector().sbx_force_x->setValue(0.0);
                getUiInspector().sbx_force_y->setValue(0.0);
                getUiInspector().sbx_force_z->setValue(0.0);
            } else {
                std::vector<btRigidBody*>& bodies = getRendererThread().getRenderer().getSelectedBodyParts();
                btVector3 forces(getUiInspector().sbx_force_x->value(),
                        getUiInspector().sbx_force_y->value(),
                        getUiInspector().sbx_force_z->value());

                for (std::vector<btRigidBody*>::iterator it = bodies.begin();
                        it != bodies.end(); ++it) {
                    btRigidBody* rigid_body = *it;
                    BodyPart* body = NULL;
                    for (int i = 0; i < creature->getNumberOfBodyParts(); ++i) {
                        if (creature->getBodyPart(i).getRigidBody() == rigid_body) {
                            body = &creature->getBodyPart(i);
                            break;
                        }
                    }
                    assert(body);
                    rigid_body->activate(true);
                    switch (type) {
                        case FT_CENTRAL_FORCE: rigid_body->applyCentralForce(forces);
                            break;
                        case FT_CENTRAL_TORQUE: rigid_body->applyTorque(forces);
                            break;
                        case FT_IMPULSE_FORCE: rigid_body->applyCentralImpulse(forces);
                            break;
                        case FT_IMPULSE_TORQUE: rigid_body->applyTorqueImpulse(forces);
                            break;
                        case FT_RELATIVE_FORCE:
                            break;
                        case FT_RELATIVE_IMPULSE:
                            rigid_body->applyImpulse(forces, btVector3(0, -body->getSizeY() / 2.0, 0));
                            break;
                        case FT_EACH_STEP:
//                            creature->setTmpValueX(forces.x());
//                            creature->setTmpValueY(forces.y());
//                            creature->setTmpValueZ(forces.z());
                            break;
                        default:
                            BDEBUG(TO_STRING(type));
                            assert(0);
                    }
                }
            }

        }
        getSimulationThread().getSimulator().getLock().unlock();
        if (play) {
            this->play();
        }
    }

    void MainWindow::clearForces( ) {
        applyForce(FT_NONE);
    }

    void MainWindow::applyCentralForce( ) {
        applyForce(FT_CENTRAL_FORCE);
    }

    void MainWindow::applyCentralTorque( ) {
        applyForce(FT_CENTRAL_TORQUE);
    }

    void MainWindow::applyImpulseForce( ) {
        applyForce(FT_IMPULSE_FORCE);
    }

    void MainWindow::applyImpulseTorque( ) {
        applyForce(FT_IMPULSE_TORQUE);
    }


    //------------------------------------------------------------------------
    //CONSTRAINTS
    //------------------------------------------------------------------------

    void MainWindow::showConstraintDetails( const Creature& creature, const Constraint& constraint ) {
        (void) creature;
        (void) constraint;
    }

    void MainWindow::loadConstraintValues( const Constraint* constraint, const int motor_index ) {
        btRotationalLimitMotor* motor = constraint->getConstraint()->getRotationalLimitMotor(motor_index);
        getUiInspector().cbx_motor_enable->setChecked(motor->m_enableMotor);
        getUiInspector().sbx_erp->setValue(motor->m_ERP);
        getUiInspector().sbx_accumulated_impulse->setValue(motor->m_accumulatedImpulse);
        getUiInspector().sbx_bounce->setValue(motor->m_bounce);
        getUiInspector().sbx_current_limit->setValue(motor->m_currentLimit);
        getUiInspector().sbx_current_limit_error->setValue(motor->m_currentLimitError);
        getUiInspector().sbx_damping->setValue(motor->m_damping);
        getUiInspector().sbx_hi_limit->setValue(motor->m_hiLimit);
        getUiInspector().sbx_limit_softness->setValue(motor->m_limitSoftness);
        getUiInspector().sbx_lo_limit->setValue(motor->m_loLimit);
        getUiInspector().sbx_max_limit_force->setValue(motor->m_maxLimitForce);
        getUiInspector().sbx_max_motor_force->setValue(motor->m_maxMotorForce);
        getUiInspector().sbx_target_velocity->setValue(motor->m_targetVelocity);
        btVector3 limits = constraint->getAngularLowerLimits();
        getUiInspector().sbx_lower_angular_dof_x->setValue(limits.x());
        getUiInspector().sbx_lower_angular_dof_y->setValue(limits.y());
        getUiInspector().sbx_lower_angular_dof_z->setValue(limits.z());
        limits = constraint->getAngularUpperLimits();
        getUiInspector().sbx_upper_angular_dof_x->setValue(limits.x());
        getUiInspector().sbx_upper_angular_dof_y->setValue(limits.y());
        getUiInspector().sbx_upper_angular_dof_z->setValue(limits.z());
    }

    void MainWindow::changedConstraintMotor( ) {
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {
            for (int i = 0; i < getUiInspector().lst_constraints->count(); ++i) {
                if (!getUiInspector().lst_constraints->item(i)->isSelected()) {
                    continue;
                }
                Constraint* constraint = &creature->getConstraint(i);
                if (getUiInspector().rbt_motor_x->isChecked()) {
                    loadConstraintValues(constraint, 0);
                } else if (getUiInspector().rbt_motor_y->isChecked()) {
                    loadConstraintValues(constraint, 1);
                } else if (getUiInspector().rbt_motor_z->isChecked()) {
                    loadConstraintValues(constraint, 2);
                } else {
                    BDEBUG("No Motor Selected");
                }
            }
        }
        getSimulationThread().getSimulator().getLock().unlock();
    }

    void MainWindow::onConstraintItemSelectionChanged( ) {
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {
            for (int i = 0; i < getUiInspector().lst_constraints->count(); ++i) {
                if (!getUiInspector().lst_constraints->item(i)->isSelected()) {
                    continue;
                }
                Constraint* constraint = &creature->getConstraint(i);
                btVector3 angular_limits = constraint->getAngularLowerLimits();
                getUiInspector().sbx_lower_angular_dof_x->setValue(angular_limits.x());
                getUiInspector().sbx_lower_angular_dof_y->setValue(angular_limits.y());
                getUiInspector().sbx_lower_angular_dof_z->setValue(angular_limits.z());
                angular_limits = constraint->getAngularUpperLimits();
                getUiInspector().sbx_upper_angular_dof_x->setValue(angular_limits.x());
                getUiInspector().sbx_upper_angular_dof_y->setValue(angular_limits.y());
                getUiInspector().sbx_upper_angular_dof_z->setValue(angular_limits.z());

                if (getUiInspector().rbt_motor_x->isChecked()) {
                    loadConstraintValues(constraint, 0);
                }
                if (getUiInspector().rbt_motor_y->isChecked()) {
                    loadConstraintValues(constraint, 1);
                }
                if (getUiInspector().rbt_motor_z->isChecked()) {
                    loadConstraintValues(constraint, 2);
                }
            }
        }
        getSimulationThread().getSimulator().getLock().unlock();
    }

    void MainWindow::setConstraintValues( Constraint* constraint, const int motor_index,
            const eConstraintChange change, const double value ) {
        btRotationalLimitMotor* motor = constraint->getConstraint()->getRotationalLimitMotor(motor_index);
        switch (change) {
            case CC_ERP:
                motor->m_ERP = value;
                break;
            case CC_ACCUMULATED_IMPULSE:
                motor->m_accumulatedImpulse = value;
                break;
            case CC_BOUNCE:
                motor->m_bounce = value;
                break;
            case CC_CURRENT_LIMIT:
                motor->m_currentLimit = value;
                break;
            case CC_CURRENT_LIMIT_ERROR:
                motor->m_currentLimitError = value;
                break;
            case CC_DAMPING:
                motor->m_damping = value;
                break;
            case CC_HI_LIMIT:
                motor->m_hiLimit = value;
                break;
            case CC_LIMIT_SOFTNESS:
                motor->m_limitSoftness = value;
                break;
            case CC_LO_LIMIT:
                motor->m_loLimit = value;
                break;
            case CC_MAX_LIMIT_FORCE:
                motor->m_maxLimitForce = value;
                break;
            case CC_MAX_MOTOR_FORCE:
                motor->m_maxMotorForce = value;
                break;
            case CC_TARGET_VELOCITY:
                motor->m_targetVelocity = value;
                break;
            case CC_ENABLE:
                motor->m_enableMotor = bool(value);
                break;
            case CC_LOWER_ANGULAR_LIMIT_X:
            case CC_LOWER_ANGULAR_LIMIT_Y:
            case CC_LOWER_ANGULAR_LIMIT_Z:
            {
                btVector3 limit = constraint->getAngularLowerLimits();
                switch (change) {
                    case CC_LOWER_ANGULAR_LIMIT_X:limit.setX(value);
                        break;
                    case CC_LOWER_ANGULAR_LIMIT_Y:limit.setY(value);
                        break;
                    case CC_LOWER_ANGULAR_LIMIT_Z:limit.setZ(value);
                        break;
                    default: BDEBUG(TO_STRING(change));
                        assert(0);
                }
                constraint->setAngularLowerLimits(limit);
                constraint->getConstraint()->setAngularLowerLimit(limit);
                break;
            }
            case CC_UPPER_ANGULAR_LIMIT_X:
            case CC_UPPER_ANGULAR_LIMIT_Y:
            case CC_UPPER_ANGULAR_LIMIT_Z:
            {
                btVector3 limit = constraint->getAngularUpperLimits();
                switch (change) {
                    case CC_UPPER_ANGULAR_LIMIT_X:limit.setX(value);
                        break;
                    case CC_UPPER_ANGULAR_LIMIT_Y:limit.setY(value);
                        break;
                    case CC_UPPER_ANGULAR_LIMIT_Z:limit.setZ(value);
                        break;
                    default: BDEBUG(TO_STRING(change));
                        assert(0);
                }
                constraint->setAngularUpperLimits(limit);
                constraint->getConstraint()->setAngularUpperLimit(limit);
                break;
            }
        }
    }

    void MainWindow::changedConstraint( eConstraintChange change, double value ) {
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {
            for (int i = 0; i < getUiInspector().lst_constraints->count(); ++i) {
                if (!getUiInspector().lst_constraints->item(i)->isSelected()) {
                    continue;
                }
                Constraint* constraint = &creature->getConstraint(i);
                if (getUiInspector().rbt_motor_x->isChecked()) {
                    setConstraintValues(constraint, 0, change, value);
                } else if (getUiInspector().rbt_motor_y->isChecked()) {
                    setConstraintValues(constraint, 1, change, value);
                } else if (getUiInspector().rbt_motor_z->isChecked()) {
                    setConstraintValues(constraint, 2, change, value);
                } else {
                    BDEBUG("No Motor Selected");
                }
            }
        }
        getSimulationThread().getSimulator().getLock().unlock();

    }

    void MainWindow::changedConstraintErp( double value ) {
        changedConstraint(CC_ERP, value);
    }

    void MainWindow::changedConstraintAccumulatedImpulse( double value ) {
        changedConstraint(CC_ACCUMULATED_IMPULSE, value);
    }

    void MainWindow::changedConstraintBounce( double value ) {
        changedConstraint(CC_BOUNCE, value);
    }

    void MainWindow::changedConstraintCurrentLimit( int value ) {
        changedConstraint(CC_CURRENT_LIMIT, double(value));
    }

    void MainWindow::changedConstraintCurrentLimitError( double value ) {
        changedConstraint(CC_CURRENT_LIMIT_ERROR, value);
    }

    void MainWindow::changedConstraintDamping( double value ) {
        changedConstraint(CC_DAMPING, value);
    }

    void MainWindow::changedConstraintHiLimit( double value ) {
        changedConstraint(CC_HI_LIMIT, value);
    }

    void MainWindow::changedConstraintLimitSoftness( double value ) {
        changedConstraint(CC_LIMIT_SOFTNESS, value);
    }

    void MainWindow::changedConstraintLoLimit( double value ) {
        changedConstraint(CC_LO_LIMIT, value);
    }

    void MainWindow::changedConstraintMaxLimitForce( double value ) {
        changedConstraint(CC_MAX_LIMIT_FORCE, value);
    }

    void MainWindow::changedConstraintMaxMotorForce( double value ) {
        changedConstraint(CC_MAX_MOTOR_FORCE, value);
    }

    void MainWindow::changedConstraintTargetVelocity( double value ) {
        changedConstraint(CC_TARGET_VELOCITY, value);
    }

    void MainWindow::changedConstraintEnable( bool enable ) {
        changedConstraint(CC_ENABLE, double(enable));
    }

    void MainWindow::changedConstraintLowerAngularLimitX( double value ) {
        changedConstraint(CC_LOWER_ANGULAR_LIMIT_X, value);
    }

    void MainWindow::changedConstraintLowerAngularLimitY( double value ) {
        changedConstraint(CC_LOWER_ANGULAR_LIMIT_Y, value);
    }

    void MainWindow::changedConstraintLowerAngularLimitZ( double value ) {
        changedConstraint(CC_LOWER_ANGULAR_LIMIT_Z, value);
    }

    void MainWindow::changedConstraintUpperAngularLimitX( double value ) {
        changedConstraint(CC_UPPER_ANGULAR_LIMIT_X, value);
    }

    void MainWindow::changedConstraintUpperAngularLimitY( double value ) {
        changedConstraint(CC_UPPER_ANGULAR_LIMIT_Y, value);
    }

    void MainWindow::changedConstraintUpperAngularLimitZ( double value ) {
        changedConstraint(CC_UPPER_ANGULAR_LIMIT_Z, value);
    }


    //Xml

    void MainWindow::creatureFromClipboard( ) {
        QClipboard& clipboard = *QApplication::clipboard();
        bool* success = new bool;
        Creature* creature = Creature::fromXml(
                clipboard.text(QClipboard::Clipboard).toStdString(),
                success);
        if (*success) {
            setCreature(*creature);
            addCreatureToWorld();
        }
        showCreatureXmlMessage(*success);
        delete success;
    }

    void MainWindow::creatureToClipboard( ) {
        QClipboard& clipboard = *QApplication::clipboard();
        getSimulationThread().getSimulator().getLock().lockForRead();
        Creature* creature = getSimulationThread().getSimulator().currentCreature();
        if (creature) {
            clipboard.setText(QString(creature->toXml().c_str()), QClipboard::Clipboard);
            showCreatureXmlMessage(true);
        }
        getSimulationThread().getSimulator().getLock().unlock();
        if (!creature) {
//            if (!getCreature().wasCreated()) {
//                getCreature().create();
//            }
//            if (!getCreature().wasSet()) {
//                getCreature().set();
//            }
            clipboard.setText(QString(creature->toXml().c_str()), QClipboard::Clipboard);
            showCreatureXmlMessage(true);
        }
    }

    void MainWindow::showCreatureXmlMessage( bool successful ) {
        std::string message("<html>Creature was ");
        if (successful) {
            message += "<font color=\"green\">SUCCESSFULLY</font> ";
        } else {

            message += "<font color=\"red\">UNSUCCESSFULLY</font> ";
        }
        message += "loaded";
        getUiInspector().lbl_xml_creature->setTextFormat(Qt::RichText);
        getUiInspector().lbl_xml_creature->setText(QString(message.c_str()));
        //        getUiInspector().lbl_xml_creature->setVisible(true);
        QTimer::singleShot(3000, this, SLOT(hideXmlMessages()));
    }

    void MainWindow::showPsoXmlMessage( bool successful ) {
        std::string message("<html>PSO was ");
        if (successful) {
            message += "<font color=\"green\">SUCCESSFULLY</font> ";
        } else {

            message += "<font color=\"red\">UNSUCCESSFULLY</font> ";
        }
        message += "loaded";
        getUiInspector().lbl_xml_pso->setTextFormat(Qt::RichText);
        getUiInspector().lbl_xml_pso->setText(message.c_str());
        //        getUiInspector().lbl_xml_pso->setVisible(true);
        QTimer::singleShot(3000, this, SLOT(hideXmlMessages()));
    }

}